package com.ming.shiro;

import com.ming.redsi.RedisUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.util.CollectionUtils;
import org.springframework.util.SerializationUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;

/**
 * 重写 sessionDao 将用户信息存储进 redis 中
 * 这里重写了shiro的增删改查，可以打四个断点，然后进行访问，你会发现很是巧妙。登录页面---》到登录成功---》退出
 * 但是我们会发现访问redis太过频繁，这样并不适合，新建类CustomSessionManager
 * @author MING
 * @date 2018/9/11 11:20
 */
public class RewriteShiroSessionDao extends AbstractSessionDAO {
    @Resource
    private RedisUtil redisUtil;

    private final String SHIRO_SESSION_PREFIX = "shiro-session";

    private String getKey(String key){
        return SHIRO_SESSION_PREFIX+key;
    }

    /**
     * 创建 session
     * @param session
     * @return
     */
    @Override
    protected Serializable doCreate(Session session) {
//        获取到 session id
        Serializable sessionId = generateSessionId(session);
        //将sessionId 和session捆绑
        assignSessionId(session,sessionId);
        saveSession(session);
        return sessionId;
    }

    /**
     * 获取 session
     * @param serializable
     * @return
     */
    @Override
    protected Session doReadSession(Serializable serializable) {
        System.out.println("RewriteShiroSessionDao");
        if(serializable == null){
            return  null;
        }
        String key = getKey(serializable.toString());
        byte[] deserialize = redisUtil.getByte(key.getBytes());
        Object deserialize1 = SerializationUtils.deserialize(deserialize);
        return (Session) deserialize1;
    }


    /**
     * 修改 session
     * @param session
     * @throws UnknownSessionException
     */
    @Override
    public void update(Session session) throws UnknownSessionException {
        saveSession(session);
    }

    /**
     * 删除 session
     * @param session
     */
    @Override
    public void delete(Session session) {
        if(session !=null && session.getId() !=null){
            String key = getKey(session.getId().toString());
            redisUtil.del(key);
        }
    }

    /**
     * 获取所有 session
     * @return
     */
    @Override
    public Collection<Session> getActiveSessions() {
        Set<String> keys = redisUtil.keys("*");
        Set<Session> sessions =new HashSet<Session>();
//        判断是否为空集合
        if(CollectionUtils.isEmpty(keys)){
            return sessions;
        }
        for(String key:keys){
            Session session =(Session)redisUtil.get(key);
            sessions.add(session);
        }
        return sessions;
    }

    private void saveSession(Session session){
        if(session !=null && session.getId() !=null){
            byte[] key = getKey(session.getId().toString()).getBytes();
            byte[] value = SerializationUtils.serialize(session);
            redisUtil.setByte(key, value);
        }
    }
}